EVENT BUBBLING
#
Lesson Objectives- Describe event bubbling
- Prove that event bubbling occurs
- Access the event parameter
- Differentiate between an event's
target
andcurrentTarget
- Stop event propagation
- Have an event handler return false
#
Describe event bubblingWhen elements are nested within the DOM, the DOM needs a way to decide which elements ought to trigger an event.
If a click event listener is set on the outer element, the green box, will a click on the inner element, the pink box, also trigger the event?
Does the pink box somehow 'block' the event? Does the "click me" text block it?
What belongs to the green box?
$('.outside').on('click', () => { console.log('OUTSIDE is clicked'); });
Nothing within the green box blocks the event. Everything belongs to the green box. No matter where inside the green box you click, you'll get the console log.
#
BubblesWhen you click on the pink box, this is the lowest level of your mouse location, the target
of the event. JS checks to see if there is an event listener on this element.
Then, the event bubbles up to the parent, the green box, and checks to see if there is a listener there.
But, it doesn't stop there!
The event bubbles up through all parents to the body, and checks that too!
The event finally stops bubbling at the document
.
#
Prove that event bubbling occursSo, if we set a listener on the pink element, the question is, will that also trigger the listener on the green one? Will it "bubble" up?
$('.outside').on('click', () => { console.log('OUTSIDE is clicked'); });
$('.inside').on('click', () => { console.log('INSIDE is clicked'); });
Clicking on the innermost element:
#
Test bubbling: Set listener on body $('.outside').on('click', () => { console.log('OUTSIDE is clicked'); });
$('.inside').on('click', () => { console.log('INSIDE is clicked'); });
$('body').on('click', () => { console.log('BODY is clicked'); });
Clicking on the innermost element:
#
Access the event parameter $('.inside').on('click', (event) => { console.log('INSIDE is clicked'); });
When the .on
method (or any JS event listener method) runs the callback function, it supplies the callback with an argument: an object that represents the event.
We can use this param in our callback. Call it what you like: you will see e
, ev
, event
, etc.
target
and currentTarget
#
Differentiate between an event's On the event
object, you can see the innermost thing that was clicked with event.target
, and the thing that has the event listener with event.currentTarget
.
Comment out the inside and body event listeners
On the outside event listener:
$('.outside').on('click', (event) => { console.log('OUTSIDE target is: ', event.target); console.log('OUTSIDE currentTarget is: ', event.currentTarget); });
If you click the green box (the outside element):
target
and currentTarget
are the same.
If you click the pink element (the inner element), we expect the event to bubble to the outside and trigger the event listener:
target
is the innermost element that was clicked: the inside pink one.
currentTarget
is the element on which the event listener is set: the outside green one.
#
Consider this $('.outside').on('click', (event) => { console.log('OUTSIDE target is: ', event.target); console.log('OUTSIDE currentTarget is: ', event.currentTarget); });
$('.inside').on('click', (event) => { console.log('INSIDE target is: ', event.target); console.log('INSIDE currentTarget is: ', event.currentTarget); });
$('body').on('click', (event) => { console.log('BODY target is: ', event.target); console.log('Body currentTarget is: ', event.currentTarget); });
If you click on the body, which listeners will be triggered? what will be the value of target
for each listener? and what will be the value of currentTarget
for each listener?
If you click on the outside box, which listeners will be triggered, what will be the value of target
for each listener? and what will be the value of currentTarget
for each listener?
If you click on the inner box, which listeners will be triggered? what will be the value of target
for each listener? and what will be the value of currentTarget
for each listener?
#
Element targeting with jQueryLet's say I make a few copies of the squares:
<div class="outside"> <p>Click me ... ?</p> <div class="inside"></div> </div>
<div class="outside"> <p>Click me ... ?</p> <div class="inside"></div> </div>
<div class="outside"> <p>Click me ... ?</p> <div class="inside"></div> </div>
By wrapping event.currentTarget
in jQuery I can use jQuery methods on the target, and only affect the elements I clicked (not the others)
$(event.currentTarget).css('background-color', 'black');
$('.outside').on('click', (event) => { $(event.currentTarget).css('background-color', 'black'); });
#
Stop event propagationIf you want to isolate an element and prevent bubbling, use
event.stopPropagation()
$('.inside').on('click', (event) => { console.log('INSIDE target is: ', event.target); console.log('INSIDE currentTarget is: ', event.currentTarget); event.stopPropagation(); });
Clicking on the inside element no longer triggers the outer event listeners:
Clicking on the outer event listener still triggers bubbling as expected:
#
Have an event handler return falseWhen using jQuery, you can use return false
within your event handlers to stop all of the default behavior associated with events, such as bubbling.
event.stopPropagation()
to stop bubblingevent.preventDefault()
to stop forms from refreshing the page
$('.outside').on('click', (event) => { console.log('OUTSIDE target is: ', event.target); console.log('OUTSIDE currentTarget is: ', event.currentTarget); return false; });
$('.inside').on('click', (event) => { console.log('INSIDE target is: ', event.target); console.log('INSIDE currentTarget is: ', event.currentTarget); return false; });
$('body').on('click', (event) => { console.log('BODY target is: ', event.target); console.log('Body currentTarget is: ', event.currentTarget); return false; });